import time

from flask import Blueprint, request, session

from src.api.https import SUCCESS, FAIL, fail_api, success_api, table_api
from src.model.ALikeModel import ALikeModel
from src.model.AritcleModel import ArticleModel
from src.model.TypeModel import TypeModel
from src.model.UserModel import UserModel
from src.utils.article_tool import ArticleTool
from src.utils.check_require import login_required, admin_required
from src.utils.picture_tool import PictureTool
from src.utils.type_tool import TypeTool
from src.utils.user_tool import UserTool
from src.init.init_db import db
from src.utils.info_tool import getmessage
from src.utils.aview_tool import AViewTool

articles_api = Blueprint("articles_api", __name__, url_prefix="/api/articles")

atool = ArticleTool()
ttool = TypeTool()
ptool = PictureTool()
utool = UserTool()
vtool = AViewTool()

all_types = ["article", "notice", "task"]


@articles_api.get("/byUser")
@login_required
def get_list_by_user():
    # 获取用户文章列表(按最新发布排序)
    uid = session["uid"]
    # 获取tid不为任务和公告的文章
    # 暂未完成 tids为任务和公告
    tids = ttool.list_task_tags() + ttool.list_announce_tags()
    articles = (
        ArticleModel.query.filter_by(uid=uid)
        .order_by(ArticleModel.createtime.desc())
        .all()
    )

    data = atool.filter_list(tids, articles)

    return success_api(data=data)


@articles_api.post("/byUserTasks")
@login_required
def get_user_task():
    # 获取用户任务列表(按最新发布查询)
    uid = session["uid"]

    types = "task"
    articles = (
        ArticleModel.query.filter_by(uid=uid)
        .order_by(ArticleModel.createtime.desc())
        .all()
    )
    data = atool.get_by_type(articles, types)

    return success_api(data=data)


@articles_api.get("/sortByViews")
def get_list_by_views():
    tids = ttool.list_task_tags() + ttool.list_announce_tags()
    articles = ArticleModel.query.order_by(ArticleModel.view.desc()).all()
    data = atool.filter_list(tids, articles)

    return success_api(data=data)


@articles_api.get("/sortByTime")
@login_required
def get_list_by_time():
    tids = ttool.list_task_tags() + ttool.list_announce_tags()
    articles = ArticleModel.query.order_by(ArticleModel.createtime.desc()).all()

    data = atool.filter_list(tids, articles)

    return success_api(data=data)


@articles_api.get("/notices")
def get_list_notices():
    types = "notice"
    articles = ArticleModel.query.order_by(ArticleModel.createtime.desc()).all()

    data = atool.get_by_type(articles, types)

    return success_api(data=data)


@articles_api.get("/tasks")
def get_list_tasks():
    types = "task"
    tid = TypeModel.query.filter_by(name="已经被领取的任务").first().tid
    articles = (
        ArticleModel.query.filter(ArticleModel.tid != tid)
        .order_by(ArticleModel.createtime.desc())
        .all()
    )
    data = atool.get_by_type(articles, types)

    return success_api(data=data)


@articles_api.post("/searchArticle")
def get_search_article():
    # 模糊搜索(根据type选择查找公告、任务或文章)
    types = request.json["type"]
    search = request.json["search"]
    search = "%" + search + "%"

    if types not in all_types:
        return fail_api(msg="未找到对应的type")
    articles = (
        ArticleModel.query.filter(ArticleModel.title.like(search))
        .order_by(ArticleModel.createtime.desc())
        .all()
    )

    data = atool.get_by_type(articles, types)
    return success_api(data=data)


@articles_api.get("/searchSelf")
@login_required
def get_searchSelf():
    # 查看自身发布的文章、公告、任务
    uid = session["uid"]
    types = request.args["type"]
    if types not in all_types:
        return fail_api(msg="未找到对应的type")

    articles = (
        ArticleModel.query.filter_by(uid=uid)
        .order_by(ArticleModel.createtime.desc())
        .all()
    )
    data = atool.get_by_type(articles, types)

    return success_api(data=data)


@articles_api.get("/searchSelfMission")
@login_required
def get_searchSelfMission():
    # 查看自身发布的任务
    uid = session["uid"]
    types = "task"

    articles = (
        ArticleModel.query.filter_by(uid=uid)
        .order_by(ArticleModel.createtime.desc())
        .all()
    )
    data = atool.get_by_type(articles, types)

    return success_api(data=data)


@articles_api.post("/getById")
def get_article_by_id():
    # 根据id获取文章
    aid = request.json["aid"]

    article = ArticleModel.query.filter_by(aid=aid).first()

    if article is None or article.audit is False:
        return fail_api("所查找文章不存在")

    data = (
        atool.get_article(article, session["uid"])
        if session.get("uid") is not None
        else atool.get_article(article, 0)
    )

    article.view = article.view + 1
    db.session.commit()
    if session.get("uid") is not None:
        vtool.add_view(aid=aid, uid=session.get("uid"))
    return success_api(data=data)


@articles_api.post("/likeArticle")
@login_required
def like_article():
    # 点赞文章
    aid = request.json["aid"]
    uid = session["uid"]

    if ALikeModel.query.filter_by(aid=aid, uid=uid).first() is not None:
        return fail_api("不可重复点赞")

    alike = ALikeModel(aid=aid, uid=uid)
    db.session.add(alike)
    db.session.commit()

    return success_api("文章点赞完成")


@articles_api.post("/cancelLikeArticle")
@login_required
def cancel_like_article():
    # 取消文章点赞
    aid = request.json["aid"]
    uid = session["uid"]

    if ALikeModel.query.filter_by(aid=aid, uid=uid).first() is None:
        return fail_api("当前未点赞")

    alike = ALikeModel.query.filter_by(aid=aid, uid=uid).first()
    db.session.delete(alike)
    db.session.commit()

    return success_api("文章点赞删除完成")


@articles_api.post("/getNewId")
@login_required
def get_new_id():
    # 初次编辑获取文章id
    global atool
    uid = request.json["uid"]
    if uid is None:
        uid = session["uid"]
    if UserModel.query.filter_by(uid=uid).first() is None:
        return fail_api("用户不存在！")
    return success_api(data=atool.init(uid))


@articles_api.post("/commit")
@login_required
def commit_article():
    # 编辑完成发布文章
    global ptool, atool, ttool
    aid = request.json["aid"]
    title = request.json["articleTitle"]
    content = request.json["content"]
    tid = request.json["tid"]
    msg = ptool.delete_not_exit(aid, content)
    if not msg["success"]:
        return fail_api(msg["err"])
    msg = atool.update_article(aid, title, content, tid)
    if not msg["success"]:
        return fail_api(msg["err"])
    return success_api("成功")


@articles_api.post("/delete")
@login_required
def delete_article():
    global atool
    aid = request.json["aid"]
    uid = session["uid"]
    vtool.delete_article_view(aid)

    msg = atool.delete_article(aid, uid)
    if not msg["success"]:
        return fail_api(msg["err"])
    else:
        return success_api("成功")


@articles_api.post("/ack")
@login_required
def ack_task():
    global atool
    aid = request.json["aid"]
    uid = session["uid"]

    article = ArticleModel.query.filter_by(aid=aid).first()
    if article is None or article.audit is False:
        return fail_api("任务不存在！")
    tid = TypeModel.query.filter_by(name="已经被领取的任务").first().tid
    if article.tid == tid:
        return fail_api("任务已被领取！")

    article.tid = tid

    db.session.commit()
    return success_api("成功")


@articles_api.post("/sortByInterest_new")
@login_required
def get_list_by_interest_new():
    print("收到用户请求，开始为其推荐文章", flush=True)
    version = request.json.get("version", "professional")  # 默认为专业版

    print(f"当前用户版本：{version}", flush=True)

    start_time = time.time()
    tids = ttool.list_task_tags() + ttool.list_announce_tags()
    articles = ArticleModel.query.order_by(ArticleModel.createtime.desc()).all()
    print("数据库检索完毕,用时:", time.time() - start_time, flush=True)

    total_process, recommendation_data = atool.filter_list_interest_new(
        tids, articles, utool.getProfile(session.get("uid")), version
    )
    print("推荐完毕,用时:", time.time() - start_time, flush=True)

    return success_api(
        data={"total_process": total_process, "recommendations": recommendation_data}
    )


@articles_api.post("/searchBykeyword")
@login_required
def get_list_by_keywords():
    keyword = request.json["keyword"]

    tids = ttool.list_task_tags() + ttool.list_announce_tags()
    articles = ArticleModel.query.order_by(ArticleModel.createtime.desc()).all()

    data = atool.filter_list_keyword(tids, articles, keyword)

    return success_api(data=data)


@articles_api.post("/searchBykeyword_interest")
@login_required
def get_list_by_keywords_interest():
    keyword = request.json["keyword"]

    tids = ttool.list_task_tags() + ttool.list_announce_tags()
    articles = ArticleModel.query.order_by(ArticleModel.createtime.desc()).all()

    data = atool.filter_list_keywords_interest_new(
        tids, articles, utool.getProfile(session.get("uid")), keyword
    )
    return success_api(data=data)
